﻿using System.Windows;
using Cqrs.StateMachineDesigner.Database;
using System.Reflection;
using System;
using System.Linq;
using System.Collections.Generic;
using Cqrs.Infrastructure;
using System.IO;
using System.Windows.Controls;
using Cqrs.Infrastructure.Aggregate;
using Cqrs.StateMachineDesigner.CustomCode;
using Ninject;
using Cqrs.Infrastructure.Database;

namespace Cqrs.StateMachineDesigner
{
    public partial class Window1 : Window
    {

        private Assembly _debugAssembly;
        private Type _aggregateType;

        public Window1()
        {
            InitializeComponent();
        }

        private void lstEvents_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            try
            {
                DisplayDomainObject();

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void btnLoadAggregate_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                AggregateList aggregates = new AggregateList();

                _debugAssembly = Assembly.LoadFrom(MyDesigner.AssemblyLocation);
                _aggregateType = _debugAssembly.GetTypes().Where(p => p.AssemblyQualifiedName == MyDesigner.AssemblyType).First();

                Guid aggregateId = aggregates.DisplayAggregates(
                    _aggregateType,
                    MyDesigner.AssemblyLocation,
                    DesignerCanvas.SmfFile,
                    DesignerCanvas.DbLocation
                 );
                if (aggregateId != Guid.Empty)
                {
                    List<Event> events = EventStoreInstance.Instance
                        .GetEventsForAggregate(aggregateId, _debugAssembly);
                    lstEvents.ItemsSource = events;
                    DisplayDomainObject();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void DisplayDomainObject()
        {
            this.MyDesigner.RemoveAllHighlights();

            txtDomainObject.Text = "";
            txtEventObject.Text = "";

            AggregateRootWithState aggregateRoot = AggregateRootWithState.Load(_aggregateType, DesignerCanvas.SmfFile);
            List<Event> selectedEvents = new List<Event>();
            List<string> highlightStates = new List<string>();
            List<HighlightTransition> highlightTransitions = new List<HighlightTransition>();

            foreach (var item in lstEvents.SelectedItems)
            {
                selectedEvents.Add((Event)item);
            }
            selectedEvents.Sort(new EventCompare());

            foreach (var item in selectedEvents)
            {
                string previousState = aggregateRoot.CurrentState.Name;
                aggregateRoot.LoadsFromHistory(new List<Event>() { item });
                highlightTransitions.Add(new HighlightTransition(previousState, item.GetType().Name));
            }


            txtDomainObject.Text = "";
            if (lstEvents.SelectedItems.Count > 0)
            {
                Event selectedEvent = (Event)lstEvents.SelectedItems[lstEvents.SelectedItems.Count - 1];
                txtEventObject.Text = selectedEvent.GetType().Name + ":" + "\n";
                txtEventObject.Text = txtEventObject.Text + ObjectDumper.Write(selectedEvent, 2);
            }
            txtDomainObject.Text = ObjectDumper.Write(aggregateRoot, 2);

            highlightStates.Add(aggregateRoot.CurrentState.Name);

            this.MyDesigner.HighlightStates(highlightStates);
            this.MyDesigner.HighlightTransitions(highlightTransitions);
        }

        private class EventCompare : IComparer<Event>
        {
            public int Compare(Event x, Event y)
            {
                return x.DateStamp.CompareTo(y.DateStamp);
            }
        }


    }


}
